package cn.fsd.service.impl;

import cn.fsd.domain.Commodity;
import cn.fsd.domain.CommodityClass;
import cn.fsd.domain.Courier;
import cn.fsd.domain.Customer;
import cn.fsd.domain.Customer_address;
import cn.fsd.domain.Order;
import cn.fsd.domain.Receipt;
import cn.fsd.domain.Station;
import cn.fsd.domain.Task;
import cn.fsd.feignclients.CustomerFeignClient;
import cn.fsd.feignclients.DeliveryFeignClient;
import cn.fsd.feignclients.StoreroomFeignClient;
import cn.fsd.mapper.CourierMapper;
import cn.fsd.mapper.ReceiptMapper;
import cn.fsd.mapper.StationMapper;
import cn.fsd.mapper.TaskMapper;
import cn.fsd.query.substation.PaymentQuery;
import cn.fsd.query.substation.TaskQuery;
import cn.fsd.query.substation.WorkloadQuery;
import cn.fsd.service.TaskService;
import cn.fsd.util.Constants;
import cn.fsd.vo.CommodityNameClassBean;
import cn.fsd.vo.PageBean;
import cn.fsd.vo.PaymentBean;
import cn.fsd.vo.PaymentRecord;
import cn.fsd.vo.TaskBean;
import cn.fsd.query.substation.WorkloadBean;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TaskServiceImpl implements TaskService {

  @Autowired
  TaskMapper taskMapper;
  @Autowired
  CustomerFeignClient customerFeignClient;
  @Autowired
  DeliveryFeignClient deliveryFeignClient;
  @Resource
  StoreroomFeignClient storeroomFeignClient;
  @Autowired
  CourierMapper courierMapper;
  @Autowired
  StationMapper stationMapper;
  @Autowired
  ReceiptMapper receiptMapper;


  @Override
  public PageBean<Task> queryStationAllTasks(TaskQuery query) {
    PageBean<Task> pageBean = new PageBean<>();

    PageHelper.startPage(query.getPageNow(), query.getPageSize());

    List<Task> taskList = taskMapper.queryByStationFinDateTypeStatus(query);

    PageInfo<Task> pageInfo = new PageInfo<>(taskList);

    pageInfo.setList(pageInfo.getList().stream().map(item -> {
      TaskBean bean = new TaskBean(item);
      Order order = customerFeignClient.getTheOrder(item.getOrder_id());
      if (order != null) {
        Customer_address address = customerFeignClient.getAddressByIdChoice(order.getCustomer_id(),
            order.getAddress_choice());
        if (address != null) {
          bean.setDelivery_address(address.getReceiver_address());
        }
        Customer customer = customerFeignClient.getCustomerById(order.getCustomer_id());
        if (customer != null) {
          bean.setCustomer_name(customer.getCustomer_name());
        }
        bean.setCommodity_num(order.getCommodity_num());
        Commodity commodity = deliveryFeignClient.getTheCommodity(order.getCommodity_id());
        if (commodity != null) {
          bean.setCommodity_name(commodity.getCommodity_name());
        }
      }
      return bean;
    }).collect(Collectors.toList()));

    pageBean.setTotalPages(pageInfo.getPages());
    pageBean.setTotalRows(pageInfo.getTotal());
    pageBean.setRowData(pageInfo.getList());

    return pageBean;
  }

  @Override
  public Task getTaskInfoById(String id) {
    Task task = taskMapper.selectByPrimaryKey(id);
    if (task == null) {
      return null;
    }

    Order order = customerFeignClient.getTheOrder(task.getOrder_id());
    TaskBean bean = new TaskBean(task);
    if (order != null) {
      bean.setTask_deliveryDate(order.getDelivery_date());
      bean.setIs_invoice(order.getIs_invoice());
      bean.setOrder_total_amount(order.getOrder_total_amount());
      Customer_address address = customerFeignClient.getAddressByIdChoice(order.getCustomer_id(),
          order.getAddress_choice());
      if (address != null) {
        bean.setDelivery_address(address.getReceiver_address());
      }
      Customer customer = customerFeignClient.getCustomerById(order.getCustomer_id());
      if (customer != null) {
        bean.setCustomer_name(customer.getCustomer_name());
        bean.setPostal_code(customer.getPostal_code());
        bean.setMobile_phone(customer.getMobile_phone());
      }
      bean.setCommodity_num(order.getCommodity_num());
      Commodity commodity = deliveryFeignClient.getTheCommodity(order.getCommodity_id());
      if (commodity != null) {
        bean.setCommodity_name(commodity.getCommodity_name());
        bean.setOriginal_price(commodity.getOriginal_price());
      }
    }
    Courier courier = courierMapper.selectByPrimaryKey(task.getCourier_id());
    if (courier != null) {
      bean.setCourier_name(courier.getCourier_name());
    }
    Station station = stationMapper.selectByPrimaryKey(task.getStation_id());
    if (station != null) {
      bean.setStation_name(station.getStation_name());
      bean.setStation_place(station.getStation_place());
      bean.setStation_phone(station.getStation_phone());
    }
    Receipt receipt = receiptMapper.selectByTaskId(task.getTask_id());
    if (receipt != null) {
      bean.setCustomer_satisfaction(receipt.getCustomer_satisfaction());
    }
    return bean;
  }

  @Override
  public void allocateCourier(Task task) {
    taskMapper.updateCourier(task);
  }

  @Override
  public PageBean<Task> getDeliveryPage(TaskQuery query) {
    PageBean<Task> pageBean = new PageBean<>();

    List<Courier> couriers = courierMapper.getCourierByName(query.getStation_id(),
        query.getCourier_name());

    PageHelper.startPage(query.getPageNow(), query.getPageSize());

    List<Task> tasks = taskMapper.selectAllocatedTask(query, couriers);

    PageInfo<Task> pageInfo = new PageInfo<>(tasks);

    pageInfo.setList(pageInfo.getList().parallelStream().map(task -> {
      TaskBean bean = new TaskBean(task);

      Order order = customerFeignClient.getTheOrder(task.getOrder_id());
      if (order != null) {
        Customer_address address = customerFeignClient.getAddressByIdChoice(order.getCustomer_id(),
            order.getAddress_choice());
        if (address != null) {
          bean.setDelivery_address(address.getReceiver_address());
        }
        Customer customer = customerFeignClient.getCustomerById(order.getCustomer_id());
        if (customer != null) {
          bean.setCustomer_name(customer.getCustomer_name());
        }
      }

      Courier courier = courierMapper.selectByPrimaryKey(task.getCourier_id());
      if (courier != null) {
        bean.setCourier_name(courier.getCourier_name());
      }
      return bean;
    }).collect(Collectors.toList()));

    pageBean.setRowData(pageInfo.getList());
    pageBean.setTotalPages(pageInfo.getPages());
    pageBean.setTotalRows(pageInfo.getTotal());

    return pageBean;
  }

  @Override
  public PageBean<Task> getReceipts(TaskQuery query) {
    PageBean<Task> pageBean = new PageBean<>();

    List<Courier> couriers = courierMapper.getCourierByName(query.getStation_id(),
        query.getCourier_name());

    PageHelper.startPage(query.getPageNow(), query.getPageSize());

    List<Task> tasks = taskMapper.getTaskByTypeCourierDate(query, couriers);

    PageInfo<Task> pageInfo = new PageInfo<>(tasks);

    pageInfo.setList(pageInfo.getList().parallelStream().map(task -> {
      TaskBean bean = new TaskBean(task);
      Order order = customerFeignClient.getTheOrder(task.getOrder_id());
      if (order != null) {
        Customer_address address = customerFeignClient.getAddressByIdChoice(order.getCustomer_id(),
            order.getAddress_choice());
        if (address != null) {
          bean.setDelivery_address(address.getReceiver_address());
        }
        Customer customer = customerFeignClient.getCustomerById(order.getCustomer_id());
        if (customer != null) {
          bean.setCustomer_name(customer.getCustomer_name());
          bean.setMobile_phone(customer.getMobile_phone());
        }
      }

      Courier courier = courierMapper.selectByPrimaryKey(task.getCourier_id());
      if (courier != null) {
        bean.setCourier_name(courier.getCourier_name());
      }
      return bean;
    }).collect(Collectors.toList()));

    pageBean.setTotalRows(pageInfo.getTotal());
    pageBean.setTotalPages(pageInfo.getPages());
    pageBean.setRowData(pageInfo.getList());

    return pageBean;
  }

  /**
   * 签收单签收货物，同时需要修改task和order的状态为已完成
   *
   * @param receipt 签收单
   */
  @Override
  public void signGoods(Receipt receipt) {
    receipt.setReceipt_id(UUID.randomUUID().toString());
    receiptMapper.insert(receipt);
    //订单到货之后需要把任务单状态改成已完成，如果订单状态为新订则直接修改订单状态为已完成
    //如果订单状态为换货则需要修改成 开始换货
    updateTaskStatus(receipt.getTask_id(), Constants.FINISHED);
    taskMapper.updateDeliveryDate(receipt.getTask_id(), new Date());
    Task task = taskMapper.selectByPrimaryKey(receipt.getTask_id());
    if (task != null) {
      Order theOrder = customerFeignClient.getTheOrder(task.getOrder_id());
      if (theOrder != null) {
        if (Objects.equals(theOrder.getOrder_type(), Constants.ORDERNEW)) {
          //新订则已完成
          customerFeignClient.changeOrderStatus(task.getOrder_id(), Constants.FINISHED);
        } else if (Objects.equals(theOrder.getOrder_type(), Constants.ORDERRETURN)) {
          //换货则开始退货
          customerFeignClient.changeOrderStatus(task.getOrder_id(), Constants.STARTREPLACE);
          storeroomFeignClient.beginExchange(task.getOrder_id());
        }
      }
    }
  }

  @Override
  public void updateTaskStatus(String task_id, String task_status) {
    System.out.println(task_id+task_status);
    taskMapper.updateTaskStatus(task_id, task_status);
  }

  @Override
  public PaymentBean queryPayment(PaymentQuery query) {

    //根据分类获取到根据查询条件筛选出来的商品列表
    List<Commodity> commodities = deliveryFeignClient.getCommodities(new CommodityNameClassBean(
        query.getClass_name(),
        query.getCommodity_name(),
        query.getFirst_class(),
        query.getSecond_class()));

    // 查询出满足时间条件的task和order
    List<PaymentRecord> paymentRecords = taskMapper.queryPayment(query, commodities);

    // 将一个商品的所有记录合并
    HashMap<String, List<PaymentRecord>> recordMap = new HashMap<>();

    paymentRecords.forEach(item -> {
      recordMap.computeIfAbsent(item.getCommodity_id(), k -> new ArrayList<>());
      recordMap.get(item.getCommodity_id()).add(item);
    });

    List<PaymentBean> payBeans = new ArrayList<>();

    recordMap.forEach((key, value) -> {
      PaymentBean bean = new PaymentBean();
      value.forEach(item -> {
        if (Objects.equals(item.getTask_type(), Constants.DELIVERY)) {
          bean.increDeliveryNum(item.getCommodity_num(), item.getOrder_total_amount());
        } else if (Objects.equals(item.getTask_type(), Constants.RETURN)) {
          bean.increReturnNum(item.getCommodity_num(), item.getOrder_total_amount());
        }
        bean.setCommodity_id(key);
        payBeans.add(bean);
      });
    });

    PaymentBean result = new PaymentBean();
    result.setRecords(payBeans);

    payBeans.forEach(item -> {
      Commodity commodity = deliveryFeignClient.getTheCommodity(item.getCommodity_id());
      if (commodity != null) {
        item.setCommodity_name(commodity.getCommodity_name());
        CommodityClass firstClass = deliveryFeignClient.getClassById(commodity.getFirst_class());
        CommodityClass secondClass = deliveryFeignClient.getClassById(commodity.getSecond_class());

        if (firstClass != null) {
          item.setFirst_class(firstClass.getClass_name());
        }
        if (secondClass != null) {
          item.setSecond_class(secondClass.getClass_name());
        }
      }
      //更新收款额和退款额
      result.increDue(item.getReceive_money(), item.getReturn_money());
    });

    //实缴额计算
    result.setActual_receive(result.getDue_receive() - result.getDue_return());

    return result;
  }

  @Override
  public PageBean<WorkloadBean> queryStationWork(WorkloadQuery query) {

    PageBean<WorkloadBean> pageBean = new PageBean<>();

    PageHelper.startPage(query.getPageNow(), query.getPageSize());

    List<WorkloadBean> workloads = taskMapper.queryWorkLoadByDate(query);

    PageInfo<WorkloadBean> pageInfo = new PageInfo<>(workloads);

    pageBean.setTotalRows(pageInfo.getTotal());
    pageBean.setRowData(pageInfo.getList());
    pageBean.setTotalPages(pageInfo.getPages());

    return pageBean;
  }
}
